﻿#region license
// Copyright (c) 2009 Mauricio Scheffer
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//      http://www.apache.org/licenses/LICENSE-2.0
//  
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#endregion

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Web;
using Castle.Windsor;
using log4net;

namespace HttpModuleInjection {
    /// <summary>
    /// Initializes and disposes Windsor-managed IHttpModules
    /// </summary>
    public class WindsorHttpModule : IHttpModule {
        private readonly IList<IHttpModule> modulesToDispose = new List<IHttpModule>();

        public void Init(HttpApplication context) {
            log.Debug("Init");
            foreach (var module in GetModules(context)) {
                var m = module;
                m.Init(context);
                if (!(m is IDisposable)) { // if module is IDisposable it will be handled by the release policy
                    modulesToDispose.Add(m);
                }
            }
        }

        private IHttpModule[] GetModules(HttpApplication context) {
            var containerAccessor = context as IContainerAccessor;
            if (containerAccessor == null)
                throw new ConfigurationErrorsException(string.Format("The Global HttpApplication instance needs to implement {0}", typeof(IContainerAccessor).FullName));
            var container = containerAccessor.Container;
            if (container == null)
                throw new ConfigurationErrorsException("HttpApplication has no container initialized");
            return container.ResolveAll<IHttpModule>();
        }

        private static readonly ILog log = LogManager.GetLogger(typeof(WindsorHttpModule));


        public void Dispose() {
            log.Debug("Dispose");
            foreach (var module in modulesToDispose)
                module.Dispose();
        }
    }
}